#ifndef __MVT_HTTP_MFORM_H__
#define __MVT_HTTP_MFORM_H__

#include "mvdef.h"

MVCXX_EXTERN_BEGIN

#include "mvt_utilities/mvt_http.h"

/**
 * @brief Content-Type 标准参考
 * @link https://www.runoob.com/http/http-content-type.html
 */

/*********************************
 *       mid level apis
 ********************************/

#define SIGN_CACHE_SIZE  512
#define BOUNDARY_LEN     40

typedef struct _mform_data
{
    mv_v8ptr_t pv8_ct_hdr;
    mv_v8ptr_t pv8_msg;
    mv_s32_t   s32_len;
    mv_s32_t   s32_fd;
    mv_v8ptr_t pv8_file_path;
    struct _mform_data *next;
}mform_data_t;

typedef struct _mform_node
{
    mv_v8_t       av8_boundary[BOUNDARY_LEN+1];
    mv_s32_t      s32_content_len;
    mv_bool_t     bl_fin;
    mform_data_t *pnode;
    /** slice 读取过程参数 */
    mv_s32_t      s32_offset;
    mform_data_t *pnode_proc;
}mform_node_t;

typedef struct _mform_http {
    mvt_http_t   hdl_http;
    mform_node_t stru_item_list;
	mv_v8_t      av8_content_type[128];
	mv_u8_t      au8_usr_data[1];
}mvt_http_mform_t;

/**
 * @brief 申请一个新的multipart/form-data类型HTTP POST句柄
 * 
 * @param s32_req_hdr_size  [in] 请求头缓存大小，一般申请1KB足够，视custom header需要扩展往上申请
 * @param s32_rsp_hdr_size  [in] 响应头缓存大小，一般申请1KB足够，视实际业务响应头需要扩展往上申请
 * @param s32_rsp_body_size [in] 响应内容缓存大小，根据实际业务响应一般满足容量申请
 * @param s32_usr_data_size [in] 用户自定义数据空间大小，可以跟随句柄一同申请出来，首地址为 "au8_usr_data"
 * @param ps32_result       [out]申请操作结果
 * @return 句柄内存空间
 * - success : 句柄内存首地址
 * -  failed : NULL
 */
mvt_http_mform_t *mvt_http_mform_new(mv_s32_t s32_req_hdr_size, mv_s32_t s32_rsp_hdr_size, mv_s32_t s32_rsp_body_size, mv_s32_t s32_usr_data_size, mv_s32ptr_t ps32_result);
/**
 * @brief 为表单添加一个消息
 * 
 * @param phdl                [in] http mform句柄
 * @param pv8_name            [in] 项目名称
 * @param pv8_msg             [in] 消息内容
 * @param s32_len             [in] 消息长度
 * @param pv8_content_type    [in] 消息类型（可选，不使用则 NULL 入参）
 * @return 添加操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 *             MV_EC_MALLOC_FAILED (内存申请失败) \n 
 */
mv_s32_t mvt_http_mform_add_msg(
    mvt_http_mform_t *phdl, mv_v8ptr_t pv8_name,
    mv_v8ptr_t pv8_msg,     mv_s32_t   s32_len,
    mv_v8ptr_t pv8_content_type);
/**
 * @brief 为表单添加一个文件（路径形式）
 * 
 * @param phdl                [in] http mform句柄
 * @param pv8_name            [in] 项目名称
 * @param pv8_filepath        [in] 文件路径
 * @param pv8_basename        [in] 文件名
 * @param pv8_content_type    [in] Content-Type（内容类型），不指定则置NULL（默认为二进制流）
 * @return 添加操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 *             MV_EC_MALLOC_FAILED (内存申请失败) \n 
 *             MV_EC_IGNORE   (项目被忽略，一般是文件类项目有异常)
 */
mv_s32_t mvt_http_mform_add_file(
    mvt_http_mform_t *phdl,  mv_v8ptr_t pv8_name,
    mv_v8ptr_t pv8_filepath, mv_v8ptr_t pv8_basename,
    mv_v8ptr_t pv8_content_type);
/**
 * @brief 为表单添加一个文件（缓存形式）
 * 
 * @param phdl                [in] http mform句柄
 * @param pv8_name            [in] 项目名称
 * @param pv8_cache           [in] 文件数据缓存
 * @param s32_len             [in] 数据长度
 * @param pv8_basename        [in] 文件名
 * @param pv8_content_type    [in] Content-Type（内容类型），不指定则置NULL（默认为二进制流）
 * @return 添加操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 *             MV_EC_MALLOC_FAILED (内存申请失败) \n 
 *             MV_EC_IGNORE   (项目被忽略，一般是文件类项目有异常)
 */
mv_s32_t mvt_http_mform_add_file2(
    mvt_http_mform_t *phdl,  mv_v8ptr_t pv8_name,
    mv_v8ptr_t pv8_cache,    mv_s32_t   s32_len,
    mv_v8ptr_t pv8_basename, mv_v8ptr_t pv8_content_type);
/**
 * @brief 清空表单已添加内容
 * 
 * @param phdl                [in] http mform句柄
 * @return 添加操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 */
mv_s32_t mvt_http_mform_content_clear(mvt_http_mform_t *phdl);
/**
 * @brief 表单通用请求头自动填充接口，自动填充一般满足交互过程标准的请求头信息
 * 
 * @param phdl     [in] http mform句柄
 * @param cpv8_url [in] 目标服务完整URL
 * @return 填充操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 * -           MV_EC_RESOURCE_LEAK (请求头缓存空间不足)
 */
mv_s32_t          mvt_http_mform_auto_complete(mvt_http_mform_t *phdl, mv_cv8ptr_t cpv8_url);
/**
 * @brief 表单自定义请求头设置接口，可以在自动填充基础上，额外追加需要的自定义请求头字段
 * 
 * @param phdl       [in] http mform句柄
 * @param cpv8_key   [in] 请求头字段名
 * @param cpv8_value [in] 请求头字段值
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_NOT_INIT (非法句柄) \n 
 * -           MV_EC_RESOURCE_LEAK (请求头缓存空间不足)
 */
mv_s32_t          mvt_http_mform_custom_header_set(mvt_http_mform_t *phdl, mv_cv8ptr_t cpv8_key, mv_cv8ptr_t cpv8_value);
/**
 * @brief 开始一次交互
 * 
 * @param phdl            [in] http mform句柄
 * @param ps32_statuscode [out] 取出响应状态码
 * @param pv8_rsp         [out] 取出响应消息体缓存首地址
 * @param s32_timeout_ms  [in] 交互超时时间（毫秒）
 * @param p_mvt_log_hdl   [in] mvt log 的句柄，置NULL时，则使用http组件内部通用句柄
 * @return 交互过程结果
 * - success : MV_EC_SUCCESS
 * -  failed : MV_EC_ABORT           (异常，且必须中断)
 *             MV_EC_INVALID_ARGS    (非法参数)
 *             MV_EC_TIMEOUT         (授权网络通信超时)
 *             MV_EC_CONNECT_ERROR   (授权网络通信服务器连接失败)
 *             MV_EC_GET_HOST_FAILED (域名解析失败)
 *             MV_EC_SOCKET_ERROR    (socket通信异常)
 *             MV_EC_FAILED          (其他错误)
 */
mv_s32_t          mvt_http_mform_do(mvt_http_mform_t *phdl, mv_s32ptr_t ps32_statuscode, mv_v8_t **pv8_rsp, mv_s32_t s32_timeout_ms, mv_vptr_t p_mvt_log_hdl);
/**
 * @brief 交互句柄注销接口（成功后，句柄会自动置NULL）
 * 
 * @param phdl [in] http mform句柄引用
 * @return 注销操作结果
 * - success : MV_EC_SUCCESS
 * -  failed : else 
 */
mv_s32_t          mvt_http_mform_dispose(mvt_http_mform_t **phdl);

#endif
